﻿/* 2012/1/1 */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.IO;
using Cosmos.Windows.Themes;
using System.Text.RegularExpressions;

namespace PictureShower
{
    public partial class ImageFolderList : UserControl
    {
        /// <summary>
        /// 停用文件夹的标志。以此标志开始的路径表示暂时停用。
        /// </summary>
        //public const string _DISABLED_FOLDER_SYMBOL = "*";

        public ImageFolderList()
        {
            InitializeComponent();

            imageFoldersListView.GridLines = true;
            imageFoldersListView.View = View.Details;
            imageFoldersListView.CheckBoxes = true;
            imageFoldersListView.ShowItemToolTips = true;
            imageFoldersListView.FullRowSelect = true;
            imageFoldersListView.HideSelection = false;
            imageFoldersListView.AllowDrop = true;            
        }

        public void LoadSettings(StringCollection imageFolders)
        {
            if (imageFolders == null)
                return;

            imageFoldersListView.Items.Clear();
            foreach (string anImageFolder in imageFolders)
            {
                /*string aPath;
                bool disabled;
                if (aFolder.StartsWith(_DISABLED_FOLDER_SYMBOL))
                {
                    aPath = aFolder.Substring(_DISABLED_FOLDER_SYMBOL.Length);
                    disabled = true;
                }
                else
                {
                    aPath = aFolder;
                    disabled = false;
                }

                ListViewItem aItem = CreateImageFolderListViewItem(aPath);
                aItem.Checked = !disabled;
                imageFoldersListView.Items.Add(aItem);*/

                try
                {
                    ImageFolderListViewItem anItem = new ImageFolderListViewItem(anImageFolder);
                    imageFoldersListView.Items.Add(anItem);
                }
                catch
                {
                    ;
                }
            }

        }

        public void SaveSettings(StringCollection imageFolders)
        {
            if (imageFolders == null)
                throw new ArgumentNullException("imageFolders");

            imageFolders.Clear();
            foreach (ListViewItem anItem in imageFoldersListView.Items)
            {
                /*string thePath;
                if (!aItem.Checked)
                    thePath = String.Concat(_DISABLED_FOLDER_SYMBOL, (string)aItem.Tag);
                else
                    thePath = (string)aItem.Tag;*/

                ImageFolderListViewItem item = (ImageFolderListViewItem)anItem;
                if (!Directory.Exists(item.FolderPath))
                {
                    MessageBox.Show(String.Format("文件夹 {0} 不存在", item.FolderPath), "保存的路径无效");
                }

                string[] patterns = new string[] { item.GroupPattern, item.IncludePattern, item.ExcludePattern };
                foreach (string pattern in patterns)
                {
                    Regex reg;
                    if (!String.IsNullOrEmpty(pattern))
                        try 
                        {
                            reg = new Regex(pattern); 
                        }
                        catch (ArgumentException ex)
                        {
                            MessageBox.Show(String.Format("{0} : {1}", pattern, ex.Message), "保存的正则表达式无效");
                        }
                }                
                
                imageFolders.Add(item.EscapeString);
            }
        }

        protected void OnSettingUpdated(EventArgs e)
        {
            if (SettingUpdated != null)
            {
                SettingUpdated(this, e);
            }
        }

        private bool ValidateAddingImageFolder(string folderPath)
        {
            if (!Directory.Exists(folderPath))
            {
                MessageBox.Show(string.Format("指定的文件夹\"{0}\"不存在。", folderPath), "添加失败");
                return false;
            }

            bool result = true;
            StringBuilder messageBuilder = new StringBuilder();
            foreach (ListViewItem anItem in imageFoldersListView.Items)
            {
                string aPath = ((ImageFolderListViewItem)anItem).FolderPath;

                if (folderPath.Equals(aPath))
                {
                    messageBuilder.AppendLine(String.Format("已存在文件夹\"{0}\"。", folderPath));
                    result = false;
                }
                else if (folderPath.Contains(aPath) && folderPath[aPath.Length] == '\\')
                    messageBuilder.AppendLine(String.Format("已存在\"{0}\"的父文件夹\"{1}\"。", folderPath, aPath));
                else if (aPath.Contains(folderPath) && aPath[folderPath.Length] == '\\')
                    messageBuilder.AppendLine(String.Format("已存在\"{0}\"的子文件夹\"{1}\"。", folderPath, aPath));
            }

            if (messageBuilder.Length > 0)
            {
                if (result)
                    MessageBox.Show(messageBuilder.ToString(), "警告");
                else
                    MessageBox.Show(messageBuilder.ToString(), "添加失败");
            }

            return result;
        }

        private void AddFolder()
        {
            string folderPath = imageFolderTextBox.Text;
            ValidateAddingImageFolder(folderPath);

            bool containSubfolders = containSubfolderCheckBox.Checked;
            GroupOption groupOption = groupOptionComboBox.GroupOption;
            imageFoldersListView.Items.Add(new ImageFolderListViewItem(folderPath, containSubfolders,
                null, null, groupOption, null, null, false));

            OnSettingUpdated(EventArgs.Empty);
        }

        private void RemoveFolder()
        {
            ListView.SelectedListViewItemCollection items = imageFoldersListView.SelectedItems;

            foreach (ListViewItem aItem in items)
            {
                imageFoldersListView.Items.Remove(aItem);
            }

            OnSettingUpdated(EventArgs.Empty);
        }

        private void UpdateFolder()
        {
            bool containSubfolder = containSubfolderCheckBox.Checked;
            string includePattern = includePatternTextBox.Text;
            string excludePattern = excludePatternTextBox.Text;
            GroupOption groupOption = groupOptionComboBox.GroupOption;
            string groupPattern = groupPatternTextBox.Text;
            string groupNamePattern = groupNamePatternTextBox.Text;
            foreach (ListViewItem anItem in imageFoldersListView.SelectedItems)
            {
                ImageFolderListViewItem theItem = (ImageFolderListViewItem)anItem;
                theItem.ContainSubfolder = containSubfolder;
                theItem.IncludePattern = includePattern;
                theItem.ExcludePattern = excludePattern;
                theItem.GroupOption = groupOption;
                theItem.GroupPattern = groupPattern;
                theItem.GroupNamePattern = groupNamePattern;
            }

            OnSettingUpdated(EventArgs.Empty);
        }

        private void BrowseFolder()
        {
            DialogResult result = imageFolderBrowserDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                imageFolderTextBox.Text = imageFolderBrowserDialog.SelectedPath;
            }
        }

        private void AddFolderByDialog()
        {
            DialogResult result = imageFolderBrowserDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                imageFoldersListView.Items.Add(new ImageFolderListViewItem(
                    imageFolderBrowserDialog.SelectedPath, false, null, null,
                    GroupOption.None, null, null, false));

                OnSettingUpdated(EventArgs.Empty);
            }
        }

        private void CheckAllFolder()
        {
            foreach (ListViewItem aItem in imageFoldersListView.Items)
                aItem.Checked = true;
        }

        private void CheckInvertFolder()
        {
            foreach (ListViewItem aItem in imageFoldersListView.Items)
            {
                aItem.Checked = !aItem.Checked;
            }
        }

        private void CheckSelectedFolder()
        {
            foreach (ListViewItem aItem in imageFoldersListView.SelectedItems)
                aItem.Checked = true;
        }

        private void UncheckSelectedFolder()
        {
            foreach (ListViewItem aItem in imageFoldersListView.SelectedItems)
                aItem.Checked = false;
        }

        
        private void imageFolderAddButton_Click(object sender, EventArgs e)
        {
            AddFolder();
        }

        private void imageFolderRemoveButton_Click(object sender, EventArgs e)
        {
            RemoveFolder();
        }

        private void imageFolderUpdateButton_Click(object sender, EventArgs e)
        {
            UpdateFolder();
        }

        private void imageFolderBrowseButton_Click(object sender, EventArgs e)
        {
            BrowseFolder();
        }

        private void imageFolderShiftUpButton_Click(object sender, EventArgs e)
        {
            ListViewItem tempItem = new ListViewItem();
            imageFoldersListView.Items.Insert(0, tempItem);

            ListView.SelectedIndexCollection selectedIndex = imageFoldersListView.SelectedIndices;
            for (int i = 0; i < selectedIndex.Count; i++)
            {
                int theIndex = selectedIndex[i];
                ListViewItem theItem = imageFoldersListView.Items[theIndex];
                imageFoldersListView.Items.RemoveAt(theIndex);
                imageFoldersListView.Items.Insert(theIndex - 1, theItem);
            }

            imageFoldersListView.Items.Remove(tempItem);

            OnSettingUpdated(EventArgs.Empty);
        }

        private void imageFolderShiftDownButton_Click(object sender, EventArgs e)
        {
            ListViewItem tempItem = new ListViewItem();
            imageFoldersListView.Items.Add(tempItem);

            ListView.SelectedIndexCollection selectedIndex = imageFoldersListView.SelectedIndices;
            for (int i = selectedIndex.Count - 1; i >= 0; i--)
            {
                int theIndex = selectedIndex[i];
                ListViewItem theItem = imageFoldersListView.Items[theIndex];
                imageFoldersListView.Items.RemoveAt(theIndex);
                imageFoldersListView.Items.Insert(theIndex + 1, theItem);
            }

            imageFoldersListView.Items.Remove(tempItem);

            OnSettingUpdated(EventArgs.Empty);
        }

        private void imageFolderCheckAllButton_Click(object sender, EventArgs e)
        {
            CheckAllFolder();
        }

        private void imageFolderCheckInvertButton_Click(object sender, EventArgs e)
        {
            CheckInvertFolder();
        }

        private void imageFolderCheckAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CheckAllFolder();
        }

        private void imageFolderCheckInvertToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CheckInvertFolder();
        }

        private void imageFolderAddToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddFolderByDialog();
        }

        private void imageFolderRemoveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveFolder();
        }

        private void imageFoldersListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            /*ListView.SelectedIndexCollection indices = imageFoldersListView.SelectedIndices;
            if (indices.Count != 0)
            {
                string path = imageFoldersListView.Items[indices[0]].SubItems[0].Text;
                imageFolderTextBox.Text = path;
                imageFolderBrowserDialog.SelectedPath = path;
            }*/
        }

        private void imageFoldersListView_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            OnSettingUpdated(EventArgs.Empty);
        }

        private void imageFoldersListView_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (e.IsSelected)
            {
                ImageFolderListViewItem theItem = (ImageFolderListViewItem)e.Item;
                imageFolderTextBox.Text = theItem.FolderPath;
                containSubfolderCheckBox.Checked = theItem.ContainSubfolder;
                includePatternTextBox.Text = theItem.IncludePattern;
                excludePatternTextBox.Text = theItem.ExcludePattern;
                groupOptionComboBox.GroupOption = theItem.GroupOption;
                groupPatternTextBox.Text = theItem.GroupPattern;
                groupNamePatternTextBox.Text = theItem.GroupNamePattern;
                
                //groupPatternTextBox.Text=th;
            }
        }

        private void imageFoldersListView_ItemDrag(object sender, ItemDragEventArgs e)
        {
            ListViewItem theItem = (ListViewItem)e.Item;

            if (theItem.Selected)
            {
                ListViewItem[] selectedItems = new ListViewItem[imageFoldersListView.SelectedItems.Count];
                imageFoldersListView.SelectedItems.CopyTo(selectedItems, 0);
                imageFoldersListView.DoDragDrop(selectedItems, DragDropEffects.Move);
            }
            else
                imageFoldersListView.DoDragDrop(e.Item, DragDropEffects.Move);
        }

        private void imageFoldersListView_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = e.AllowedEffect;
        }

        private void imageFoldersListView_DragOver(object sender, DragEventArgs e)
        {            
            /*
            if (((e.KeyState & shiftKeyState) == shiftKeyState) && ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move))
                e.Effect = DragDropEffects.Move;
            else if (((e.KeyState & controlKeyState) == controlKeyState) && ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy))
                e.Effect = DragDropEffects.Copy;
            else if (((e.KeyState & altKeyState) == altKeyState) && ((e.AllowedEffect & DragDropEffects.Link) == DragDropEffects.Link))
                e.Effect = DragDropEffects.Link;
            else
                e.Effect = DragDropEffects.None;
            */
            
            Point targetPoint = imageFoldersListView.PointToClient(new Point(e.X, e.Y));
            int targetIndex = imageFoldersListView.InsertionMark.NearestIndex(targetPoint);
            if (targetIndex > -1)
            {
                Rectangle itemBounds = imageFoldersListView.GetItemRect(targetIndex);
                if (targetPoint.Y > itemBounds.Top + (itemBounds.Height / 2))
                {
                    imageFoldersListView.InsertionMark.AppearsAfterItem = true;
                }
                else
                {
                    imageFoldersListView.InsertionMark.AppearsAfterItem = false;
                }
            }
            imageFoldersListView.InsertionMark.Index = targetIndex;
        }

        private void imageFoldersListView_DragLeave(object sender, EventArgs e)
        {
            imageFoldersListView.InsertionMark.Index = -1;
        }

        private void imageFoldersListView_DragDrop(object sender, DragEventArgs e)
        {
            int targetIndex = imageFoldersListView.InsertionMark.Index;

            if (targetIndex == -1)
                targetIndex = 0;

            if (imageFoldersListView.InsertionMark.AppearsAfterItem)
                targetIndex++;

            
            if (e.Data.GetDataPresent(DataFormats.StringFormat))
            {
                string path = e.Data.GetData(DataFormats.StringFormat) as string;
                if (path != null)
                {
                    ValidateAddingImageFolder(path);
                    imageFoldersListView.Items.Insert(targetIndex++
                        , new ImageFolderListViewItem(path, false, null, null,
                            GroupOption.None, null, null, false));
                    OnSettingUpdated(EventArgs.Empty);
                }
            }
            else if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] filePaths = e.Data.GetData(DataFormats.FileDrop) as string[];
                if (filePaths != null)
                {
                    foreach (string aPath in filePaths)
                    {
                        ValidateAddingImageFolder(aPath);
                        imageFoldersListView.Items.Insert(targetIndex++
                            , new ImageFolderListViewItem(aPath, false, null, null,
                                GroupOption.None, null, null, false));
                    }
                    OnSettingUpdated(EventArgs.Empty);
                }
            }
            else if (e.Data.GetDataPresent(typeof(ListViewItem)))
            {
                ListViewItem draggedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
                imageFoldersListView.Items.Insert(targetIndex, new ImageFolderListViewItem((ImageFolderListViewItem)draggedItem));
                imageFoldersListView.Items.Remove(draggedItem);
                OnSettingUpdated(EventArgs.Empty);
            }
            else if (e.Data.GetDataPresent(typeof(ListViewItem[])))
            {
                ListViewItem[] selectedItems = (ListViewItem[])e.Data.GetData(typeof(ListViewItem[]));

                for (int i = 0; i < selectedItems.Length; i++)
                {
                    imageFoldersListView.Items.Insert(targetIndex++, new ImageFolderListViewItem((ImageFolderListViewItem)selectedItems[i])).Selected = true;
                }

                for (int i = 0; i < selectedItems.Length; i++)
                {
                    imageFoldersListView.Items.Remove(selectedItems[i]);
                }
                OnSettingUpdated(EventArgs.Empty);
            }
        }

        private void imageFoldersListView_Resize(object sender, EventArgs e)
        {
            ListView self = sender as ListView;
            pathColumnHeader.Width = self.Width - 135;
        }

        [Category("Property Changed")]
        [Description("Occurs when any setting have been updated.")]
        public event EventHandler SettingUpdated;
    }
}
